/*
 * funcionesDeConsola.c
 *
 *  Created on: 03/11/2011
 *      Author: utn_so
 */

#include "raid.h"
/*
struct listaSelect {
	int32_t tipo; //si es File System va 1 si es PPD va 0
	int32_t descriptor;
	int32_t status;// si esta activo es 1 si es 0 no lo esta, solo funciona para el PPD
	int32_t identificadorPPD;
	struct listaSelect *siguiente;
}typedef listaSelect;
*/



void lectura_distribuir(){
	struct listaSelect *punteroAuxiliarSelect;
	struct nipc_protocolpunteroNIPC;
	struct listaSelect *punteroAuxSelectParaLimpiar;
	struct estructuraLeer *punteroEstructuraLeerAux;
	struct estructuraLeer *punteroEstructuraLeer;
	int32_t i;

	for(i=0;(i<500) && (punteroFrenteLeer!=NULL);i++){
		punteroAuxiliarSelect=punteroFteSelect;
		while(punteroAuxiliarSelect){

			if((punteroAuxiliarSelect->status==1)&&(punteroFrenteLeer!=NULL)&&(punteroAuxiliarSelect->cantidadPedido<6)&&(punteroAuxiliarSelect->descriptor != -1)){


				punteroEstructuraLeerAux=punteroFrenteLeer;
				punteroFrenteLeer=punteroFrenteLeer->siguiente;
				if(punteroFrenteLeer==NULL){
					punteroFinLeer=NULL;
				}
				nodoLectura_crear(&punteroEstructuraLeer,punteroEstructuraLeerAux->numeroSector,punteroEstructuraLeerAux->sincro);
				if (punteroAuxiliarSelect->descriptor == -1) {
					punteroEstructuraLeerAux->siguiente=punteroFrenteLeer;
					punteroFrenteLeer=punteroEstructuraLeerAux;
				}else{
					pthread_mutex_lock(&mutexPtroBackup);
					colaLectura_meter(&(punteroAuxiliarSelect->punteroBackup),(&punteroAuxiliarSelect->punteroBackupFin), &punteroEstructuraLeer);
					pthread_mutex_unlock(&mutexPtroBackup);
					punteroAuxiliarSelect->cantidadPedido++;
					punteroEstructuraLeer=NULL;
					printf("Se mandó al descriptor %d, el sector %d\n", punteroAuxiliarSelect->descriptor, punteroEstructuraLeerAux->numeroSector);
					if (punteroAuxiliarSelect->descriptor == -1) {
						punteroEstructuraLeerAux->siguiente=punteroFrenteLeer;
						punteroFrenteLeer=punteroEstructuraLeerAux;
					}else{
					log_info(log,"LEER", "Se mandó al descriptor %d, el sector %d", punteroAuxiliarSelect->descriptor, punteroEstructuraLeerAux->numeroSector);
					NIPC_enviar(punteroAuxiliarSelect->descriptor,'6',0,"",punteroEstructuraLeerAux->numeroSector);
					free(punteroEstructuraLeerAux);
					}
				}

			}
			if((punteroAuxiliarSelect->cantidadPedido>5)||(punteroAuxiliarSelect->tipo==1)||(punteroAuxiliarSelect->descriptor == -1)){
			punteroAuxiliarSelect=punteroAuxiliarSelect->siguiente;
			}
		}


		punteroAuxSelectParaLimpiar=punteroFteSelect;
		while(punteroAuxSelectParaLimpiar){
			if(punteroAuxSelectParaLimpiar->status==1){
				punteroAuxSelectParaLimpiar->cantidadPedido=0;
			}
			punteroAuxSelectParaLimpiar=punteroAuxSelectParaLimpiar->siguiente;
		}

	}

}


void escribir_distribuir(){
	struct listaSelect *punteroAuxiliarSelect;

	struct estructuraEscribir *punteroEstructuraEscribirAux;
	int32_t i;

	for(i=0;(i<500) && (punteroFrenteEscribir!=NULL);i++){
		punteroAuxiliarSelect=punteroFteSelect;
		while(punteroAuxiliarSelect){


			if(punteroAuxiliarSelect->status==1){
				punteroEstructuraEscribirAux=punteroFrenteEscribir;
				printf("Se mandó A ESCRIBIR al descriptor %d, el sector %d\n", punteroAuxiliarSelect->descriptor, punteroEstructuraEscribirAux->numeroSector);
				log_info(log,"ESCRIBIR", "Se mandó al descriptor %d, el sector %d", punteroAuxiliarSelect->descriptor, punteroEstructuraEscribirAux->numeroSector);

				NIPC_enviar(punteroAuxiliarSelect->descriptor,'5',TAMANIO_SECTOR,punteroEstructuraEscribirAux->infoSector,punteroEstructuraEscribirAux->numeroSector);

				/*NIPC_enviar(&punteroNIPC,punteroAuxiliarSelect->descriptor,'5',TAMANIO_SECTOR,punteroEstructuraEscribirAux->infoSector,punteroEstructuraEscribirAux->numeroSector);
				free(punteroNIPC->payload);
				free(punteroNIPC);*/
			}
			punteroAuxiliarSelect=punteroAuxiliarSelect->siguiente;
		}
		nodoColaEscritura_liberar(&punteroFrenteEscribir,&punteroFinEscribir);
	}
}


void sincronizar(){
	//averiguar tamanio
	int32_t i;
	struct listaSelect *punteroAuxiliarSelect;
	pthread_mutex_lock(&mutexSecTot);
	//Para tomar el tiempo que tarda en sincronizar

	for(i = 0; i < 250 && ultimoLeido < sectoresTotales && sincronizador == 1; i++){
		pthread_mutex_lock(&mutexPtroFteSelectAux);
		punteroAuxiliarSelect = punteroFteSelect;
		pthread_mutex_unlock(&mutexPtroFteSelectAux);
		while(punteroAuxiliarSelect && ultimoLeido < sectoresTotales){
			if(punteroAuxiliarSelect->status==1){
			pthread_mutex_lock(&mutexDescriptor);
			printf("Se mandó A LEER PARA SINCRONIZAR al descriptor %d, el sector %d\n", punteroAuxiliarSelect->descriptor, ultimoLeido);
				NIPC_enviar(punteroAuxiliarSelect->descriptor,'7',0,"",ultimoLeido);
			pthread_mutex_unlock(&mutexDescriptor);
				/*NIPC_enviar(&punteroNIPC,punteroAuxiliarSelect->descriptor,'7',0,"",ultimoLeido);
				free(punteroNIPC->payload);
				free(punteroNIPC);*/
				ultimoLeido++;
			}
			pthread_mutex_lock(&mutexPtroSelectAux);
			punteroAuxiliarSelect=punteroAuxiliarSelect->siguiente;
			pthread_mutex_unlock(&mutexPtroSelectAux);
		}
	}
	pthread_mutex_unlock(&mutexSecTot);

	pthread_mutex_lock(&mutexPtroFteEscritura);
	pthread_mutex_lock(&mutexPtroFte);
	for(i=0;(i<250) && (punteroFrenteSincro!=NULL) && sincronizador == 1;i++){


		NIPC_enviar(descriptorASincronizar,'5',TAMANIO_SECTOR,punteroFrenteSincro->infoSector,punteroFrenteSincro->numeroSector);
		printf("Se mandó A ESCRIBIR PARA SINCRONIZAR al descriptor %d, el sector %d\n", descriptorASincronizar, punteroFrenteSincro->numeroSector);
		ultimoEscrito++;
		//hay que cambiar el desc de aca arriba, va a ir en variable
		nodoColaEscritura_liberar(&punteroFrenteSincro,&punteroFinSincro);
	}
	pthread_mutex_unlock(&mutexPtroFte);
	pthread_mutex_unlock(&mutexPtroFteEscritura);
	if(ultimoEscrito==sectoresTotales){
		pthread_mutex_lock(&mutexDescriptorASincronizar);
		descriptor_cambiarStatus (&punteroFteSelect, &punteroFinSelect,descriptorASincronizar);
		pthread_mutex_unlock(&mutexDescriptorASincronizar);
		ultimoLeido=0;
		ultimoEscrito=0;
		sincronizador=0;
		//int32_t segundos;
	//	segundos=time(NULL)-anterior;
//		printf("Tiempo total de sincronizacion:total %d y %d minutos y %d segundos\n", segundos,segundos/60,segundos%60);


	}
}


void descriptor_cambiarStatus (struct listaSelect **punteroFteSelect,struct listaSelect **punteroFinSelect,int32_t descriptorASincronizar) {
	struct listaSelect *punteroAux=*punteroFteSelect;
	if (*punteroFteSelect == NULL)
					return;
	while(punteroAux!=NULL) {
		if (punteroAux->descriptor != descriptorASincronizar) {
			punteroAux=punteroAux->siguiente;
		} else {
			punteroAux->status=1;
			return;
		}
	}
}
/* Pone en funcionamiento la consola del raid*/
void consola_RAIDenFuncionamiento(void){
	printf("El RAID se ha puesto en funcionamiento\n");
}

/*
void consola_conexionNuevoPlanificador(int32_t identificador)
{

}
void consola_sincronizacionDiscos(int32_t tiempoInicio,int32_t tiempoFin)
{

}
void consola_writeEnDiscos(void)
{

}
void consola_readEnDisco(int32_t discoQueSeEstaLeyendo)
{

}


*/
